<xsl:stylesheet version="1.1"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/2000/svg"
                xmlns:xlink="http://www.w3.org/1999/xlink"
                xmlns:random="http://exslt.org/random"
                xmlns:math="http://exslt.org/math"
                xmlns:exsl="http://exslt.org/common"
                xmlns:temp="http://temp.org/temp"
                extension-element-prefixes="exsl"
                exclude-result-prefixes="random math exsl">
    
	<xsl:param name="room-id"/>
	<xsl:param name="page-margin">20</xsl:param>
    <xsl:param name="page-width">400</xsl:param>
    <xsl:param name="page-height">600</xsl:param>
 	<xsl:param name="room-width" select="$page-width - $page-margin * 2"/>            
 	<xsl:param name="room-height" select="($page-height - $page-margin * 3) div 2"/>
    <xsl:param name="width" select="$page-width * 2"/>
    <xsl:param name="height" select="$page-height"/>
    <xsl:param name="word-height" select="$room-height"/>
    <xsl:param name="word-bar-height">40</xsl:param>
    <xsl:param name="text-height">16</xsl:param>
    <xsl:param name="text-margin">10</xsl:param>
	
  	<xsl:preserve-space elements="tokens"/>
  	<xsl:output method="xml"/>
  
  	
  	<xsl:include href="game_svg_tower.xslt"/>
  	<xsl:include href="game_svg_princess.xslt"/>
  	<xsl:include href="game_svg_door.xslt"/>
  	<xsl:include href="game_svg_bird.xslt"/>
  
  	<xsl:template match="/">
		<svg 
			width="{$width + $page-margin * 2}" 
			height="{$height + $page-margin * 2}" 
			viewBox="{-$page-margin} {-$page-margin} {$width + $page-margin * 2} {$height + $page-margin * 2}" 
			version="1.1"
			onload="init(evt);">
			<script type="application/ecmascript"> 
<![CDATA[
	var wordQueue = new Array();
	var doorWords = new Array();
	var things = new Object();
	var svgns = "http://www.w3.org/2000/svg";
	var xhtmlns = "http://www.w3.org/1999/xhtml";
	
	function init(evt)
	{
		// populate things and their triggers
		]]><xsl:apply-templates select="game/rooms/room[@id=$room-id]//thing" mode="javascript-init"/><![CDATA[
		// evaluate the triggers in case there's anything busting to talk
		evalTriggers();
		
		doorWords.push('tell');
		doorWords.push('me');
		doorWords.push('you');
		doorWords.push('name');
		
		say(evt, 'door', doorWords);
	}
	
	function evalTriggers()
	{
	}

    function queue(evt,wordID) 
    {
    	// add the word to the queue
		wordQueue.push(wordID);
		// find the original
		var symbolElement = document.getElementById('symbol_'+wordID);
		// clone
		var symbolElementClone = symbolElement.cloneNode(true);
		// drop in the text box
    	var speechBar = document.getElementById('speech_bar');
		speechBar.appendChild(symbolElementClone);
 	}
 	
 	function clear(evt)
 	{
 		while( wordQueue.length > 0 ) 
 		{
 			wordQueue.pop();
 		}
    	var speechBar = document.getElementById('speech_bar');
		// remove all children
		while( speechBar.childNodes.length > 0 ) 
		{
			speechBar.removeChild( speechBar.lastChild );
		} 		
 	}
 	
 	function learn(evt, wordID)
 	{
 		var wordElement = document.getElementById('word_'+wordID);
 		if( (wordElement.opacity == null || wordElement.opacity <= 0) && wordElement.lastChild.localName != 'animate' ) 
 		{
 			var animation = document.createElementNS(svgns, 'animate');
 			animation.setAttributeNS(null, 'attributeName', 'opacity');
 			animation.setAttributeNS(null, 'to', 1 );
 			animation.setAttributeNS(null, 'begin', 'indefinite');
 			animation.setAttributeNS(null, 'dur', '1s' );
 			animation.setAttributeNS(null, 'fill', 'freeze');
 			wordElement.appendChild(animation);
 			animation.beginElement();
	 		//wordElement.setAttributeNS(null, 'opacity', 1);
	 	}
 	}
 	
 	function sayTo(evt, targetID)
 	{
 		// remove existing one
		var oldSpeechElements = document.getElementsByName('speech');
		for( var i=oldSpeechElements.length; i>0; ) 
		{
			i--;
 			oldSpeechElements[i].parentNode.removeChild(oldSpeechElements[i]);			
		} 
 	
 		// check the wordQueue
 		say(evt, 'princess', wordQueue);
 		 
 		if( targetID == 'bird'  )
 		{
 			if( wordQueue.length == 4 && wordQueue[0] == 'tell' && wordQueue[1] == 'me' && wordQueue[2] == 'me' && wordQueue[3] == 'name' )
 			{
	 			var birdWords = new Array();
	 			birdWords.push('princess-name');
				say(evt, targetID, birdWords); 				
			}
 		}
 		if( targetID == 'door' ) 
 		{
 			if( wordQueue.length == 0 ) 
 			{
	 			say(evt, targetID, doorWords);
	 		}
	 		else if( wordQueue.length == 1 && wordQueue[0] == 'princess-name' ) 
	 		{
	 			say(evt, targetID, new Array('yes'));
	 			// open the door
	 			var doorElement = document.getElementById('thing_door');
	 			doorElement.setAttributeNS(null, 'transform', 'scale(-1, 1)');
	 			//alert('You Have Escaped!');
	 		}
	 		else
	 		{
	 			say(evt, targetID, new Array('no'));
	 		}
 		}
		clear(evt);
 		
 	}
 	
 	function say(evt, sourceID, words)
 	{
		if( words.length > 0 ) 
		{
	 		var sourceElement = document.getElementById('thing_'+sourceID);
	 		if( sourceElement != null ) 
	 		{
	 			// work out the width of the sentence
	 			var body = document.createElementNS(xhtmlns, 'body');
	 			body.setAttributeNS(null, 'style', 'margin:0;padding:0;');
	 			var width = 0;
	 			var height = 0;
	 			for( var i = 0; i < words.length; i++ ) 
	 			{
	 				var wordId = words[i];
	 				learn(evt, wordId);
	 				var symbolElement = document.getElementById('symbol_'+wordId);
	 				if( symbolElement != null ) 
	 				{
						width += symbolElement.clientWidth;
						if( symbolElement.clientHeight > height ) 
						{
							height = symbolElement.clientHeight;
						}
						// also append to body area
						var symbolElementClone = symbolElement.cloneNode(true);
						body.appendChild(symbolElementClone); 					
	 				}
	 			}
	 			var bb = sourceElement.getBBox();
	 			
	 			var foreignObject = document.createElementNS(svgns, 'foreignObject');
	 			foreignObject.setAttributeNS(null, 'x', bb.x + (bb.width - width) / 2);
	 			foreignObject.setAttributeNS(null, 'y', bb.y - 10 - height);
	 			foreignObject.setAttributeNS(null, 'width', width);
	 			foreignObject.setAttributeNS(null, 'height', height);
	 			foreignObject.appendChild(body);
	 			
	 			// say words
	 			var speechBubble = document.createElementNS(svgns, 'path');
	 			speechBubble.setAttributeNS(null, 'd',  
	 				'M '+(bb.x + bb.width / 2)+' '+ bb.y + 
	 				' l 0 -10 l -'+(width / 2)+' 0 l 0 -'+height+' l '+width+' 0 l 0 '+height+' l -'+(width / 3)+' 0 z'
	 			);
	 			speechBubble.setAttributeNS(null, 'fill', 'white');
	 			speechBubble.setAttributeNS(null, 'stroke', 'black');
	 			
	 			var g = document.createElementNS(svgns, 'g');
	 			g.setAttributeNS(null, 'name', 'speech');
	 			g.appendChild(speechBubble);
	 			g.appendChild(foreignObject);
	 			
	 			sourceElement.parentNode.appendChild(g);
	 		}
	 	}
 	}
 ]]> 
  				</script>
	    	<g id="book">
				<rect x="0" y="0" width="{$page-width}" height="{$page-height}" fill="ivory" stroke="black"/>
				<rect x="{$page-width}" y="0" width="{$page-width}" height="{$page-height}" fill="ivory" stroke="black"/>
	    	
	    		<g transform="translate({$page-width + $page-margin}, {$page-margin})" id="room">
		    		<xsl:apply-templates select="game/rooms/room[@id=$room-id]">
		    			<xsl:with-param name="room-width" select="$room-width"/>
		    			<xsl:with-param name="room-height" select="$room-height"/>
		    		</xsl:apply-templates>
		    	</g>
	    		<g transform="translate({$page-width + $page-margin}, {$room-height + $page-margin * 2})">
	    			<rect x="0" y="0" width="{$room-width - $page-margin - $word-bar-height}" height="{$word-bar-height}" fill="white" stroke="black"/>
					<foreignObject x="0" y="0" width="{$room-width - $page-margin - $word-bar-height}" height="{$word-bar-height}">
						<!-- XHTML content goes here -->
					    <body xmlns="http://www.w3.org/1999/xhtml">
							<div id="speech_bar" style="line-height:{$word-bar-height}px;">
							</div>
					    </body>
					</foreignObject>
					<rect x="{$room-width - $word-bar-height}" y="0" width="{$word-bar-height}" height="{$word-bar-height}" fill="red" stroke="black" onclick="clear(evt);">
					
					</rect>
	    		</g>
	    		<g transform="translate({$page-width + $page-margin}, {$room-height + $page-margin * 3 + $word-bar-height})">
	    			<xsl:apply-templates select="game/words"/>
	    		</g>
	    		<g id="journal" transform="translate(0, 0)">
	    			<xsl:apply-templates select="game/rooms/room[@id=$room-id]/journal"/>
	    		</g>
	        </g>
		</svg>	  
  	</xsl:template>

	<xsl:template match="words">
		<xsl:param name="x">0</xsl:param>
		<xsl:param name="y">0</xsl:param>
		<xsl:param name="max-line-height">0</xsl:param>
		<xsl:param name="index" select="1"/>
		<xsl:param name="last" select="count(word)"/>
		<xsl:if test="$last >= $index">
			<xsl:variable name="symbol-width" select="word[$index]/symbol/@width"/>
			<xsl:variable name="symbol-height" select="word[$index]/symbol/@width"/>
			<xsl:variable name="new-x" select="$x + $symbol-width"/>
			<xsl:variable name="word-id" select="word[$index]/@id"/>
			<xsl:variable name="player-id" select="/game/things/thing[@player = 'true']/@id"/>
			<xsl:choose>
				<xsl:when test="$new-x >= $page-width - ($page-margin * 2)">
					<g id="word_{$word-id}" opacity="0" transform="translate(0, {$y + $max-line-height})">
						<foreignObject x="0" y="0" width="{$symbol-width}" height="{$symbol-height}">
							<!-- XHTML content goes here -->
						    <body xmlns="http://www.w3.org/1999/xhtml" style="margin:0;padding:0;">
								<svg width="{$symbol-width}" height="{$symbol-height}" xmlns="http://www.w3.org/2000/svg" version="1.1" id="symbol_{$word-id}">
									<xsl:copy-of select="word[$index]/symbol/*"/>
						      	</svg>
						    </body>
						</foreignObject>
						<rect x="0" y="0" width="{$symbol-width}" height="{$symbol-height}" fill="white" stroke="black" opacity="0.1" onclick="queue(evt, '{$word-id}');"/>
					</g>
					<xsl:apply-templates select=".">
						<xsl:with-param name="x" select="$symbol-width"/>
						<xsl:with-param name="y" select="$y + $max-line-height"/>
						<xsl:with-param name="max-line-height" select="$symbol-height"/>
						<xsl:with-param name="index" select="$index + 1"/>
						<xsl:with-param name="last" select="$last"/>
					</xsl:apply-templates>															
				</xsl:when>
				<xsl:otherwise>
					<g id="word_{$word-id}" opacity="0" transform="translate({$x}, {$y})">
						<foreignObject x="0" y="0" width="{$symbol-width}" height="{$symbol-height}">
							<!-- XHTML content goes here -->
						    <body xmlns="http://www.w3.org/1999/xhtml" style="margin:0;padding:0;">
								<svg width="{$symbol-width}" height="{$symbol-height}" xmlns="http://www.w3.org/2000/svg" version="1.1" id="symbol_{$word-id}">
									<xsl:copy-of select="word[$index]/symbol/*"/>
						      	</svg>
						    </body>
						</foreignObject>
						<rect x="0" y="0" width="{$symbol-width}" height="{$symbol-height}" fill="white" stroke="black" opacity="0.1" onclick="queue(evt, '{$word-id}');"/>
					</g>
					<xsl:variable name="new-max-line-height">
						<xsl:choose>
							<xsl:when test="$max-line-height > $symbol-height">
								<xsl:value-of select="$max-line-height"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:value-of select="$symbol-height"/>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:variable>
					<xsl:apply-templates select=".">
						<xsl:with-param name="x" select="$new-x"/>
						<xsl:with-param name="y" select="$y"/>
						<xsl:with-param name="max-line-height" select="$new-max-line-height"/>
						<xsl:with-param name="index" select="$index + 1"/>
						<xsl:with-param name="last" select="$last"/>
					</xsl:apply-templates>															
				</xsl:otherwise>
			</xsl:choose>
		</xsl:if>
	</xsl:template>
	
	<xsl:template match="journal">
		<g id="journal">
			<foreignObject x="{$page-margin}" y="{$page-margin}" width="{$page-width - ($page-margin) * 2}" height="{$height - $page-margin}">
				<!-- XHTML content goes here -->
			    <body xmlns="http://www.w3.org/1999/xhtml">
			    	<xsl:apply-templates select="*" mode="journal"/>
			    </body>
			</foreignObject>
	    </g>		
	</xsl:template>
	
	<xsl:template match="p" mode="journal">
   		<p xmlns="http://www.w3.org/1999/xhtml" style="font-family:fantasy; font-size:{$text-height}px;">
     		<xsl:apply-templates select="* | text()" mode="journal"/>
     	</p>
	</xsl:template>
	
	<xsl:template match="text()" mode="journal">
		<xsl:value-of select="."/>
	</xsl:template>

	<xsl:template match="br" mode="journal">
   		<br xmlns="http://www.w3.org/1999/xhtml"/>
	</xsl:template>
	
	<xsl:template match="word" mode="journal">
		<!--  embed a svg image -->
		<xsl:variable name="word-id" select="@id"/>
   		<nobr xmlns="http://www.w3.org/1999/xhtml">
		<xsl:text>(</xsl:text>
		<xsl:variable name="symbol-width" select="/game/words/word[@id=$word-id]/symbol/@width"/>
		<xsl:variable name="symbol-height" select="/game/words/word[@id=$word-id]/symbol/@height"/>
		<svg width="{$symbol-width}" height="{$symbol-height}" xmlns="http://www.w3.org/2000/svg" version="1.1" onload="learn(evt, '{$word-id}');">
			<xsl:copy-of select="/game/words/word[@id=$word-id]/symbol/*"/>
      	</svg>
		</nobr>		
		<xsl:text>)</xsl:text>
	</xsl:template>
 	
 	<xsl:template match="thing">
  		<xsl:param name="base-x"/>
  		<xsl:param name="base-y"/>
  		<xsl:param name="width"/>
  		<xsl:param name="height"/>
	 	<xsl:param name="state"/>
	 	<g transform="translate({$base-x}, {$base-y})">
	 	 	<g id="thing_{@id}" onclick="sayTo(evt, '{@id}');">
	 	 		<xsl:apply-templates select="." mode="render">
	 	 			<xsl:with-param name="base-x">0</xsl:with-param>
			  		<xsl:with-param name="base-y">0</xsl:with-param>
			  		<xsl:with-param name="width" select="$width"/>
			  		<xsl:with-param name="height" select="$height"/>
				 	<xsl:with-param name="state" select="$state"/>
	 	 		</xsl:apply-templates>
	 	 	</g>	
 	 	</g>
 	</xsl:template>
 	
 	<xsl:template match="thing" mode="javascript-init">
 		<xsl:text>
 		{
 			var thing = new Object();
 			var actions = new Array();
 			</xsl:text>
 			<xsl:for-each select="@*">
 				<xsl:text>
 			thing['</xsl:text><xsl:value-of select="local-name(.)"/><xsl:text>'] = '</xsl:text><xsl:value-of select="."/><xsl:text>';</xsl:text>
 			</xsl:for-each>
			<xsl:text>
			{</xsl:text>
				<xsl:apply-templates select="action" mode="javascript-init"/>
				<xsl:text>
				actions.push(action);
			}</xsl:text>
 			<xsl:text>
 			thing.actions = actions;
 			things['</xsl:text><xsl:value-of select="@id"/><xsl:text>'] = thing;
 		}
 		</xsl:text>
 	</xsl:template>
 	
 	<xsl:template match="action" mode="javascript-init">
		<xsl:text>
		var action = new Object();
		// triggers
		var triggers = new Array();
		// stuff to do
		var operations = new Array();
		</xsl:text>
		
		<xsl:text>
		action.triggers = triggers;
		action.operations = operations;
		</xsl:text>
 	</xsl:template>
 	
</xsl:stylesheet>